//
// Created by tang on 23-2-8.
//

#include "core/timespan.hpp"
#include "core/log.hpp"

#include <time.h>

#if _WIN32

#include <Windows.h>

#define MS_PER_SEC      1000ULL     // MS = milliseconds
#define US_PER_MS       1000ULL     // US = microseconds
#define HNS_PER_US      10ULL       // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns)
#define NS_PER_US       1000ULL

#define HNS_PER_SEC     (MS_PER_SEC * US_PER_MS * HNS_PER_US)
#define NS_PER_HNS      (100ULL)    // NS = nanoseconds
#define NS_PER_SEC      (MS_PER_SEC * US_PER_MS * NS_PER_US)

pi_time_t platform_get_time()
{
    static LARGE_INTEGER ticksPerSec;
    LARGE_INTEGER ticks;

    if (!ticksPerSec.QuadPart) {
        QueryPerformanceFrequency(&ticksPerSec);
        if (!ticksPerSec.QuadPart) {
            errno = ENOTSUP;
            return 0.0;
        }
    }

    QueryPerformanceCounter(&ticks);

    return (pi_time_t)(ticks.QuadPart / ticksPerSec.QuadPart) + 
    (pi_time_t)(((ticks.QuadPart % ticksPerSec.QuadPart) * NS_PER_SEC) / ticksPerSec.QuadPart) * 1e-9;
}
#else
pi_time_t platform_get_time()
{
    struct timespec value;
    clock_gettime (CLOCK_MONOTONIC, &value);
    return (pi_time_t)value.tv_sec + (pi_time_t)value.tv_nsec * 1e-9;
}
#endif
